from fastapi import APIRouter, Depends, HTTPException, Header
from sqlalchemy.orm import Session
from typing import Optional
import bcrypt
import secrets
from datetime import timedelta

from app.database import get_db
from app import models, schemas
from app.redis_client import redis_client

router = APIRouter(prefix="/admin-auth", tags=["管理员认证"])

# Token有效期：7天
TOKEN_EXPIRE_DAYS = 7


def generate_admin_token() -> str:
    """生成随机token"""
    return secrets.token_urlsafe(32)


def verify_password(plain_password: str, hashed_password: str) -> bool:
    """验证密码"""
    return bcrypt.checkpw(plain_password.encode('utf-8'), hashed_password.encode('utf-8'))


@router.post("/login", response_model=schemas.Response)
async def admin_login(
    request: schemas.AdminLoginRequest,
    db: Session = Depends(get_db)
):
    """管理员登录"""
    # 查询管理员
    admin = db.query(models.Admin).filter(
        models.Admin.username == request.username
    ).first()
    
    if not admin:
        raise HTTPException(status_code=401, detail="用户名或密码错误")
    
    # 验证密码
    if not verify_password(request.password, admin.password_hash):
        raise HTTPException(status_code=401, detail="用户名或密码错误")
    
    # 生成token
    token = generate_admin_token()
    
    # 存储到Redis，有效期7天
    redis_key = f"admin_token:{token}"
    redis_client.setex(
        redis_key,
        timedelta(days=TOKEN_EXPIRE_DAYS),
        admin.username
    )
    
    return schemas.Response(
        message="登录成功",
        data=schemas.AdminLoginResponse(
            token=token,
            username=admin.username
        )
    )


async def verify_admin_token(
    token: Optional[str] = Header(None),
    db: Session = Depends(get_db)
) -> models.Admin:
    """验证管理员token（依赖函数）"""
    if not token:
        raise HTTPException(status_code=401, detail="未登录")
    
    # 从Redis中获取username
    redis_key = f"admin_token:{token}"
    username = redis_client.get(redis_key)
    
    if not username:
        raise HTTPException(status_code=401, detail="登录已过期，请重新登录")
    
    # 查询管理员
    admin = db.query(models.Admin).filter(
        models.Admin.username == username
    ).first()
    
    if not admin:
        raise HTTPException(status_code=401, detail="管理员不存在")
    
    return admin


@router.post("/logout", response_model=schemas.Response)
async def admin_logout(
    token: Optional[str] = Header(None)
):
    """管理员登出"""
    if token:
        redis_key = f"admin_token:{token}"
        redis_client.delete(redis_key)
    
    return schemas.Response(message="登出成功")

